iT邦幫忙

2023 iThome 鐵人賽

DAY 2
1
Software Development

CRUD仔的一生(上集)系列 第 2

[ACID] 事務(Transaction)

  • 分享至 

  • xImage
  •  

Transaction

前言

Transaction事務(交易),我喜歡將它翻譯成事務,
因為他與買賣交易完全無關係,
代表的其實是要將一段SQL丟進資料庫系統中,最後取得回覆。
至於Transaction事務在資料庫系統中是如何運作的呢?
需要符合哪些規則,讓我們一步一步的了解。

Remark: 有時會將Transaction寫成TX來表示

命運

我們知道在電腦之中(這裡的電腦指的是馮紐曼架構的電腦),
每個指令(這裡的"指令"是指機器碼machine code)都會使用到I/O與CPU,
逃離不了Fetch、Decode、Execute

  1. Fetch(I/O):從memory讀取指令,將指令放到指令暫存器中
  2. Decode(CPU):解析指令暫存器中的
  3. Execute(CPU):執行指令
    的循環。

想當然爾,資料庫的CRUD同樣逃離不了該命運。
當循序操作時(同一個時間裡整台電腦就只能執行該指令),
一個指令一個指令的輸入,當該指令I/O或CPU閒置時,
無法讓其他指令使用,將造成許多浪費,且效率極差。

改變

就是因為循序操作(Serialized),所以造成了I/O與CPU的浪費,這裡我們稱為idle,俗稱占著茅坑不拉屎。
因此我們可以透過pipelining的技術,讓同一時間不只有一個指令。 達到指令A有idle時,可以將資源讓出來給其他需要的指令,這樣的交錯操作(interleaved),可以增加throughput。

並發性(Concurrency)

但隨之而來的將會面臨著並發(Concurrency)問題,可能會有多個指令同時操作著同一筆資料,造成覆蓋等問題。
所以,目標就是在交錯操作(interleaved)的設計之下,必須讓每個操作都如同循序操作(Serialized)般的如其效果。
要讓同一個資料避免同一個時間被兩個指令修改,第一個想法就是在操作該筆資料時,加上鎖,讓其他也想操作該筆資料的指令先在外面等,等前面的指令使用完了,再將該筆資料讓出來給下一個指令操作。
在程式之中可能會這樣寫。

wLock.lock();
try{
    // do some instructions
}finally{
    wLock.unlock();
}

可以發現我們在執行指令的上下加上了lock,以確保在操作這些指令時,所使用到的所有資料與變數都為自己所用,並且在此期間不被其他指令污染。
再來可以發現,我們的try{...} 其實可以塞入很多指令,塞到滿出來想要塞多少都可以。這裡我們稱為c.s. (Critical section臨界區段)

Transaction(TX)

剛剛看到了在撰寫程式時的lock。

wLock.lock();
try{
    // do some instructions
}finally{
    wLock.unlock();
}

聰明的小夥伴們是否覺得非常熟悉啊,長相幾乎跟資料庫之中的transaction非常類似。

tx.start()
try {
    // some sql instructions
} finally {
    tx.commit();
}

其實,Transaction說明白的就是一種Critical section,裡面可以放1~n個SQL instructions組成一個Transaction,確保該Transaction運行之中資料不被污染。
SQL instructions主要操作就是CRUD,更簡化的操作就是讀/寫與cpu的操作,

Remark:
- Tx?: transaction。
- R(A): R表示read sql instructions(select),A表示所使用到的資料。
- W(A): W表示write,sql instructions(create,update,delete),A表示所使用到的資料。

何時使用Transaction(TX)

先問個問題
當我們操作DB時,大部分都只是"單句"的CRUD,
單句的CRUD大約佔了80%的使用量,
在資料庫中,何時會使用到tx。

A. 因為是單句CRUD,所以剩下的20%使用tx。
B. 100%全部都使用到tx。
C. 0%使用tx,我都直接在應用層上鎖。
D. 以上皆非。

其實在db內是100%使用tx
就算只有一句也是tx,
因為資料庫系統中的default值是把auto commit=ture
所以丟進來後會自動幫忙加上tx start、tx commit,
因此tx才是資料庫真正的操作單位,每一次的sql instructions都是一次的tx。

結語:

我們前面講解了Transaction其實就是為了避免在交錯操作(interleaved)的設計之下Sql指令之間污染資料,因此加上類似lock的設計,誕生了Transaction這個名詞。
理念就是想要:

  1. 利用交錯操作(interleaved)增加throughput。
  2. 交錯操作(interleaved)的設計之下期望達到與循序操作(Serialized)相同的結果,加上lock概念的Transaction避免下Sql指令之間污染資料。

所以同時達到了事務隔離(Isolation):當有多個TX並發時,TX之間如預期的不相互污染。
有了上面的概念,自然就可以理解資料庫系統為了增加Transaction的throughput,讓一般的麻瓜也能輕易的達到高效能的CRUD操作。
這兩項性質。

誤區

  1. Transaction翻譯雖然叫做交易但其實跟現實生活中的買賣交易完全無關。

參考資料

資料庫系統概論


上一篇
[前言] 寫後端一定ipad資料庫
下一篇
[ACID] SX鎖(SXLock)
系列文
CRUD仔的一生(上集)32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言